<?php

namespace app\merchants\services;


use app\common\libs\OnlinePay;
use app\common\loader\ModelMerchant;
use app\common\loader\ModelSystem;
use app\common\loader\ModelVirtual;
use app\common\loader\Services;
use app\common\traits\RechargeTrait;
use think\Exception;
use yiqiniu\extend\facade\Logger;

/**
 * 充值
 */
class RechargeService extends BaseService
{

    use RechargeTrait;

    /**
     * 商户充值
     * @param string $merID
     * @param int $payWay
     * @param float $payMoney
     * @param int $opUser
     * @param string $memo
     * @return mixed
     * @throws \think\Exception
     * @throws \Exception
     */
    public function balance(string $merID, int $payWay, float $payMoney, int $opUser, string $memo = '')
    {
        //插入充值记录
        $payOrder = ModelMerchant::RechargeLog()->addPayLog($merID, $payWay, $payMoney, $opUser, $memo);

        $info['pay_order'] = $payOrder;
        return $info;
    }


    /**
     * 显示支付信息
     * @param string $mer_id 商户编号
     * @param string $payOrder 支付单号
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \yiqiniu\extend\exception\ApiException
     */
    public function payInfo(string $mer_id, string $payOrder): array
    {
        $info = ModelMerchant::RechargeLog()->getPayOrderInfo($payOrder);

        $qrcode_url = '';
        if ($info['pay_status'] === 0) {
            $pay_result = $this->makePayQrcode($mer_id, $payOrder, $info['pay_money']);
            if ($pay_result['result'] === false) {
                api_exception(API_ERROR, $pay_result['msg']);
            }
            $qrcode_url = $pay_result['data']['qrcode_url'];
        }
        $pay_way_title = config('system.pay_way');
        $pay_way_tag = $pay_way_title[$info['pay_way']] ?? '未知';
        return [
            'pay_qrcode' => $qrcode_url,
            'pay_order' => $payOrder,
            'pay_way' => $info['pay_way'],
            'pay_way_tag' => $pay_way_tag,
            'pay_money' => $info['pay_money'],
            'real_money' => $info['real_money'],
            'pay_status' => $info['pay_status'],
            'pay_status_tag' => $info['pay_status'] === 1 ? '已支付' : '未支付',
            'pay_time' => $info['pay_time'],
            'out_pay_order' => $info['out_pay_order'],
            'memo' => $info['memo'],
        ];
    }

    /**
     * 生成支付的二维码信息
     * @param string $merID
     * @param string $payOrder
     * @param float $payMoney
     * @return array
     * @throws \Exception
     */
    private function makePayQrcode(string $merID, string $payOrder, float $payMoney): array
    {
        // 检测订单是否可以支付
        $merTitle = ModelMerchant::MerchantInfo()->where('mer_id', $merID)->rawValue('title');
        $memo = '商户:' . $merID . $merTitle . ',余额充值';
        $attach = 'recharge';

        return OnlinePay::getInstance()->PayMoney($payOrder, $payMoney, $attach . '|' . $payOrder, $memo);
    }


    /**
     * 购买虚码
     * @param string $merId 商户ID
     * @param int $admin_id 操作人
     * @param int $package_id 虚码套餐ID
     * @param string $memo 备注
     * @return mixed
     */
    public function buyVirtual(string $merId, int $admin_id, int $package_id, string $memo = '')
    {
        // 1. 获取套餐信息
        // 2. 从余额中扣除相应的金额
        // 3. 加上对应的虚码
        // 4. 插入交易记录

        $packageInfo = ModelSystem::SystemVirtualPackage()->getValidInfo($package_id);
        if (empty($packageInfo)) {
            throw  new Exception('套餐不存在,请重新选择');
        }
        // 虚码交易的记录
        return ModelVirtual::VirtualTransaction()->buyVirtual($merId, $packageInfo['money'], $packageInfo['num'], $admin_id, $memo);
    }


    /**
     * 虚码交易记录
     * @param $option
     * @return mixed
     * @throws Exception
     * @throws \think\db\exception\DbException
     */
    public function virtualLog($option)
    {
        $list = ModelVirtual::VirtualTransaction()->pageList($option);
        Services::Helper()->showListTitle($list['data'],
            ['merchant_info' => 'mer_id', 'merchant' => 'op_user', 'shop' => 'shop_id'],
            ['type' => 'system.transaction_type']);
        return $list;
    }

    /**
     * 充值流水记录
     * @param array $option
     * @return mixed
     * @throws \think\db\exception\DbException
     */
    public function moneyLogPage(array $option)
    {
        $pageList = ModelMerchant::MerchantMoneyLog()->pageList($option);
        Services::Helper()->showListTitle($pageList['data'], [], ['type' => 'system.money_log_type']);
        return $pageList;
    }




    /**
     * 追加支付信息到日志中
     * @param array $row 记录信息
     * @param array $payInfo 支付状态
     * @param array $pay_status 支付状态信息
     * @return void
     */
    public function appendPayInfoToLog(array &$row, array $payInfo, array $pay_status): void
    {
        // 支付状态
        $row['pay_status'] = 0;
        $row['pay_status_tag'] = '无红包';
        $row['pay_fail_msg'] = '';
        $row['point_status_tag'] = '无积分';
        if ($row['status'] === 1) {
            if ($row['point'] > 0) {
                $row['point_status'] = 1;
                $row['pay_status_tag'] = '已发放';
            }
            if (!empty($payInfo)) {
                $row['pay_status'] = $payInfo['pay_status'];
                $row['pay_status_tag'] = $pay_status[$row['pay_status']] ?? '';
                if ($row['pay_status'] === 2) {
                    $row['pay_fail_msg'] = $payInfo['pay_fail_reason'];
                }
            }
        }
    }


    public function pay_success(array $notify_data, string &$errorMsg)
    {
        if (empty($notify_data['out_order_no']) || empty($notify_data['pay_order_no'])) {
            $errorMsg = 'out_order_no 或 pay_order_no 为空';
            return false;
        }
        $result = false;
        try {
            // 调用线上付款
            $result = ModelMerchant::RechargeLog()->onlinePaySuccess($notify_data['out_order_no'], $notify_data['pay_order_no']);

        } catch (Exception $e) {
            Logger::exception($e);
            $errorMsg = "success";
        }
        return $result;
    }


}
